package AgentesClassificadores;

import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.List;


import AgentesConcurso.AgenteDecisor;
import Ontologias.PredicadoConcurso;
import Ontologias.PredicadoResultado;
import Ontologias.PredicadoProposta;
import Ontologias.ResultadoProposta;


import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import jade.wrapper.AgentController;
import jade.wrapper.ContainerController;
import jade.wrapper.StaleProxyException;

@SuppressWarnings("serial")
public class AgenteReceptorProposta extends jade.core.Agent {

	private List<PredicadoProposta> l_PredProposta;
	private PredicadoConcurso pConc;
	private List<ClassificacaoProposta> lClassProp;
	public List<ACLMessage> l_resp;
	private AgenteDecisor agDecisor;

	public void setup() {

		try {
			DFAgentDescription dfd = new DFAgentDescription();
			dfd.setName( getAID() );
			ServiceDescription sd  = new ServiceDescription();
			sd.setType( "AgenteReceptorProposta" );
			sd.setName( getLocalName() );
			dfd.addServices(sd);
			DFService.register(this, dfd );  
		}
		catch (FIPAException fe) { 
			fe.printStackTrace(); 
		}

		Object[] args = getArguments();

		this.agDecisor = (AgenteDecisor)args[0];

		this.pConc = (PredicadoConcurso)args[1];

		l_PredProposta = new ArrayList<PredicadoProposta>(args.length - 2);
		int i = 2;
		while(args[i] != null) {
			l_PredProposta.add((PredicadoProposta)args[i]);
			i++;
		}
		analisa_propostas();
	}



	public void analisa_propostas() {
		lClassProp = new ArrayList<ClassificacaoProposta>();
		boolean first = true;
		float min = 0;


		ACLMessage msg;

		for(PredicadoProposta predProp : l_PredProposta) {
			msg = null;
			enviar_msg("AgenteClassificadorFornecedor", predProp.getFornecedor());

			do {
				msg = this.blockingReceive();
			} while(msg == null);

			float classificacaoFornecedor = 0.5F;
			try {
				classificacaoFornecedor = Float.parseFloat(msg.getContent());
			} catch (Exception e) {
				classificacaoFornecedor = 0.5F;
			}
			ClassificacaoProposta cpro = new ClassificacaoProposta(predProp, classificacaoFornecedor,this);
			lClassProp.add(cpro);
			if (first) {
				min = predProp.getOrcamento();
				first = false;
			}
			else if (predProp.getOrcamento() < min) min = predProp.getOrcamento();
		}
		List<ResultadoProposta> lResultProp = new LinkedList<ResultadoProposta>();

		for(ClassificacaoProposta cPro : lClassProp) {
			float pPreco = cPro.getOrcamento()/min;
			cPro.avaliaProposta(pConc,pPreco);
			ResultadoProposta resultProp = new ResultadoProposta(cPro.getClassificacaoFornecedor(), cPro.getNomeFornecedor(), cPro.getOrcamento(), cPro.getAvaliacaoProposta(), cPro.getFacilidadePagamento(), cPro.getAvaliacaoVeiculos(), cPro.getVeicAvaliados());
			lResultProp.add(resultProp);
		}

		PredicadoResultado predResult = new PredicadoResultado();
		predResult.setPropostas(lResultProp);

		create_agente_decisor(predResult,pConc);
	}




	public void create_agente_decisor(PredicadoResultado pRes,PredicadoConcurso pConc) {
		if (agDecisor == null){
			ContainerController cc;
			AgentController ac;
			Object[] args_list = new Object[2];
			args_list[0] = pRes;
			args_list[1] = pConc;

			cc = getContainerController();
			try {
				ac = cc.createNewAgent(pConc.getNome() + (new GregorianCalendar()).getTimeInMillis() + "_decisor", "AgentesConcurso.AgenteDecisor", args_list);
				ac.start();
			} catch (StaleProxyException e) {
				e.printStackTrace();
			}
		} else {
			agDecisor.actualizar(pRes, pConc);
		}

	}

	public void enviar_msg(String tipo_dest, String s_msg) {

		ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
		DFAgentDescription dfd = new DFAgentDescription();
		ServiceDescription sd  = new ServiceDescription();
		sd.setType(tipo_dest);
		dfd.addServices(sd);

		DFAgentDescription[] result = {};
		try {
			result = DFService.search(this, dfd);

		} catch (FIPAException e) {
			e.printStackTrace();
		}

		for (DFAgentDescription df : result) {
			msg.addReceiver(df.getName());
		}

		msg.setContent(s_msg);
		send(msg);

	}
}

